<?php
require_once dirname(__FILE__).'/../../../config.php';
require_once cf\Config::path.'/api/admin.php';

error_reporting(E_ALL & ~E_NOTICE);

function parseRfc822Date($date) 
{ 
  if (!preg_match('/^(?:(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun), )?(?P<day>\d{1,2}) (?P<month>Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (?P<year>\d{4}) (?P<hour>\d{2}):(?P<minute>\d{2})(?::(?P<second>\d{2}))? (?P<timezone>UT|GMT|EST|EDT|CST|CDT|MST|MDT|PST|PDT|[A-IK-Z]|[+-]\d{4})$/', $date, $matches)) {
	//throw new Exception("'$date' is not a valid Rfc822Date format"); 
	return time();
  }
    

  switch($matches['month']) 
  { 
    case 'Jan': 
      $matches['month'] = 1; 
      break; 
    case 'Feb': 
      $matches['month'] = 2; 
      break; 
    case 'Mar': 
      $matches['month'] = 3; 
      break; 
    case 'Apr': 
      $matches['month'] = 4; 
      break; 
    case 'May': 
      $matches['month'] = 5; 
      break; 
    case 'Jun': 
      $matches['month'] = 6; 
      break; 
    case 'Jul': 
      $matches['month'] = 7; 
      break; 
    case 'Aug': 
      $matches['month'] = 8; 
      break; 
    case 'Sep': 
      $matches['month'] = 9; 
      break; 
    case 'Oct': 
      $matches['month'] = 10; 
      break; 
    case 'Nov': 
      $matches['month'] = 11; 
      break; 
    case 'Dec': 
      $matches['month'] = 12; 
      break; 
    default: 
      throw new Exception('This should not even be possible...'); 
  } 
  switch($matches['timezone']) 
  { 
    case 'UT': // Universal Time 
    case 'GMT': // Universal Time 
      $matches['timezone'] = 0*3600; 
      break; 
    case 'EST': // Eastern: - 5 
      $matches['timezone'] = -5*3600; 
      break; 
    case 'EDT': // Eastern: - 4 
      $matches['timezone'] = -4*3600; 
      break; 
    case 'CST': // Central: - 6 
      $matches['timezone'] = -6*3600; 
      break; 
    case 'CDT': // Central: - 5 
      $matches['timezone'] = -5*3600; 
      break; 
    case 'MST': // Mountain: - 7 
      $matches['timezone'] = -7*3600; 
      break; 
    case 'MDT': // Mountain: - 6 
      $matches['timezone'] = -6*3600; 
      break; 
    case 'PST': // Pacific: -8 
      $matches['timezone'] = -8*3600; 
      break; 
    case 'PDT': // Pacific: -7 
      $matches['timezone'] = -7*3600; 
      break; 
    // Military (letters, J is not used): 
    case 'A': 
      $matches['timezone'] = -1*3600; 
      break; 
    case 'B': 
      $matches['timezone'] = -2*3600; 
      break; 
    case 'C': 
      $matches['timezone'] = -3*3600; 
      break; 
    case 'D': 
      $matches['timezone'] = -4*3600; 
      break; 
    case 'E': 
      $matches['timezone'] = -5*3600; 
      break; 
    case 'F': 
      $matches['timezone'] = -6*3600; 
      break; 
    case 'G': 
      $matches['timezone'] = -7*3600; 
      break; 
    case 'H': 
      $matches['timezone'] = -8*3600; 
      break; 
    case 'I': 
      $matches['timezone'] = -9*3600; 
      break; 
    case 'K': 
      $matches['timezone'] = -10*3600; 
      break; 
    case 'L': 
      $matches['timezone'] = -11*3600; 
      break; 
    case 'M': 
      $matches['timezone'] = -12*3600; 
      break; 
    case 'N': 
      $matches['timezone'] = 1*3600; 
      break; 
    case 'O': 
      $matches['timezone'] = 2*3600; 
      break; 
    case 'P': 
      $matches['timezone'] = 3*3600; 
      break; 
    case 'Q': 
      $matches['timezone'] = 4*3600; 
      break; 
    case 'R': 
      $matches['timezone'] = 5*3600; 
      break; 
    case 'S': 
      $matches['timezone'] = 6*3600; 
      break; 
    case 'T': 
      $matches['timezone'] = 7*3600; 
      break; 
    case 'U': 
      $matches['timezone'] = 8*3600; 
      break; 
    case 'V': 
      $matches['timezone'] = 9*3600; 
      break; 
    case 'W': 
      $matches['timezone'] = 10*3600; 
      break; 
    case 'X': 
      $matches['timezone'] = 11*3600; 
      break; 
    case 'Y': 
      $matches['timezone'] = 12*3600; 
      break; 
    case 'Z': 
      $matches['timezone'] = 0*3600; 
      break; 
    default: 
      if ($matches['timezone'][0] == '+' || $matches['timezone'][0] == '-') 
      { 
        $matches['timezone'] = (int)substr($matches['timezone'], 0, 3)*3600 + (int)($matches['timezone'][0].substr($matches['timezone'], 3)) * 60; 
      } 
      else 
    throw new Exception('That should not even be possible...'); 
  } 
  return gmmktime($matches['hour'], $matches['minute'], (int)$matches['second'], $matches['month'], $matches['day'], $matches['year']) - $matches['timezone']; 
}

function onStartTag($parser, $name, $attrs) {
	global $currTag, $channel, $item, $image;
	$currTag = null;
	if ($name == 'RSS') {
		$channel = true;
	} elseif ($name == 'CHANNEL' && $channel) {
		$channel = array();
	} elseif ($name == 'ITEM') {
		if ($item === false) {	//first <ITEM>
			updateChannel($channel);
		}
		$item = array();
	} elseif ($name == 'IMAGE') {
		$image = array();
	} else {
		$currTag = strtolower($name);
	}
}
function onText($parser, $data) {
	global $currTag, $channel, $item, $image;
	if (!$currTag) {
		return;
	}
	if (is_array($image)) {
		$image[$currTag] .= $data;
	} elseif (is_array($item)) {
		if ($currTag == 'p') {
			$currTag = 'description';
		}
		$item[$currTag] .= $data;
	} elseif (is_array($channel)) {
		$channel[$currTag] .= $data;
	}
}
function onEndTag($parser,$name) {
	global $currTag, $item, $itemsCount, $abort, $channelID, $channel, $image;
	if ($name=='ITEM') {
		saveItem($item);
		++$itemsCount;
		$item = null;
	} elseif ($name=='IMAGE') {
		if (is_array($channel)) {
			$channel['image'] = $image;
		}
		$image = false;
	} elseif ($name=='RSS') {
		if (!$abort) {
			cf\execQuery("UPDATE cf_rss_channel SET added_count=:count WHERE id=:id",array('id'=>$channelID,'count'=>$itemsCount));
		}
	}
	$currTag = null;
}

function updateChannel($channel){
	if (!is_array($channel)) {
		return;
	}
	$dt = time();
	if (array_key_exists('lastbuilddate',$channel)) {
		$dt = parseRfc822Date($channel['lastbuilddate']);
	} elseif (array_key_exists('pubdate',$channel)) {
		$dt = parseRfc822Date($channel['pubdate']);
	}
	
	global $channelID, $categories, $abort;	
	$lastUpdate = cf\query2var("SELECT UNIX_TIMESTAMP(last_upload) FROM cf_rss_channel WHERE id=:id", array('id'=>$channelID));
	if ($lastUpdate >= $dt) {
		$abort = true;
		return;
	}
	$channel['date'] = $dt;
	cf\execQuery("UPDATE cf_rss_channel SET last_upload=FROM_UNIXTIME(:dt),added_count=0 WHERE id=:id",array('id'=>$channelID,'dt'=>$dt));

	//delete old
	$catDel = cf\query2vector("SELECT cf_news_in_category.id FROM cf_news INNER JOIN cf_news_in_category ON cf_news.id=cf_news_in_category.news_id WHERE cf_news.rss_chanel_id=$channelID");
	$qDel = cf\createQuery('DELETE FROM cf_news_in_category WHERE id=:id');
	foreach ($catDel as $cat) {
		$qDel->setParam('id',$cat);
		$qDel->execute();
		$qDel->close();
	}
	cf\execQuery("DELETE FROM cf_news WHERE rss_chanel_id=:id",array('id'=>$channelID));
	
	$categories = cf\query2vector("SELECT category_id FROM cf_rss_channel_to_category WHERE channel_id=:id", array('id'=>$channelID));
}

function saveItem($item){
	global $channelID, $categories, $db, $abort;
		
	if (!$item || $abort) {
		return;
	}

	static $q = null;
	cf\createStaticQuery($q,"INSERT INTO cf_news (name,dt,short_txt,url,rss_chanel_id) VALUES(:name, FROM_UNIXTIME(:dt),:descr,:link,$channelID)");
	$q->setParam('name',array_key_exists('title',$item) ? $item['title'] : $item['description']);
	$q->setParam('dt',array_key_exists('pubdate',$item) ? parseRfc822Date($item['pubdate']) : time());
	$q->setParam('descr',array_key_exists('description',$item) ? $item['description'] : $item['title']);
	$q->setParam('link',array_key_exists('link',$item) ? $item['link'] : (array_key_exists('guid',$item) ? $item['guid'] : $channel['date']));
	$q->execute();
	$q->close();
	
	$news = $db->lastInsertId();
	static $qCat = null;
	cf\createStaticQuery($qCat,"INSERT INTO cf_news_in_category (category_id,news_id) VALUES(:cat,:news)");
	foreach ($categories as $cat) {
		$qCat->setParam('cat',$cat);
		$qCat->setParam('news',$news);
		$qCat->execute();
		$qCat->close();
	}
}

function importRSS($channelID) 
{
	global $abort;

	$parser = xml_parser_create('UTF-8');
	xml_set_element_handler($parser, 'onStartTag', 'onEndTag');
	xml_set_character_data_handler($parser, 'onText');
	
	$f = fopen(cf\query2var("SELECT channel_url FROM cf_rss_channel WHERE id=:id",array('id'=>$channelID)),'r');
	if ($f===false) {
		throw new Exception("Could't open file:"+$settings['url']);
	}		
	while (($data=fread($f, 1024)) && !$abort) {
		if (!xml_parse($parser, $data, feof($f))) {
			throw new Exception(sprintf("XML error: %s at line %d",
				xml_error_string(xml_get_error_code($parser)),
				xml_get_current_line_number($parser))
			);
		}
	}
	xml_parser_free($parser);
	fclose($f);	
}

$channel = $item = $image = $currTag = $abort = false;
$categories = array();
$itemsCount = 0;

try {
	$_SERVER['DOCUMENT_ROOT'] = getcwd()."/../../../..";

	if ($argv[1]=='all') {
		$channelIDs = cf\query2vector("SELECT id FROM cf_rss_channel");
		foreach ($channelIDs as $channelID) {
			$channel = $item = $image = $currTag = $abort = false;
			$categories = array();
			$itemsCount = 0;
			importRSS($channelID);
		}
	} else {
		$channelID = (int)$argv[1];
		importRSS($channelID);
	}

} catch(Exception $e){
	print_r($e);
}

return 0;
?>